// 📦 引入工具库
const _ = require("lodash");
const path = require("path");
const fs = require("fs");

// 📦 ESM 支持模块加载
const esm = require("esm");
const requireModule = esm(module);

// 📦 项目依赖模块
const { readAllValues } = requireModule(
  "../../../awakened-potential/helpers/readAllValues.js"
);
const checkAccuracy = requireModule("../../utils/checkAccuracy.js");

// ✅ 读取历史开奖数据（模拟全部）
const allValues = readAllValues("m");

// ✅ 号码池（01 ~ 49）
const allNumbers = Array.from({ length: 49 }, (_, i) =>
  (i + 1).toString().padStart(2, "0")
);

// ✅ 是否使用窗口
const useWindow = true;
// ✅ 窗口大小
const windowSize = 118;

// ✅ 基于斜率分析策略
/**
 * 计算当前期和上一期号码的差值（斜率）
 * - 如果差值大，说明号码发生了较大变化，可能代表“渐变”的号码。
 * @param {Array} temp - 当前窗口数据
 * @returns {Array} - 选出的32个号码
 */
function select32BySlopeAnalysis(temp) {
  const slopeMap = {};

  // 计算前后两期之间的差值（斜率）
  for (let i = 1; i < temp.length; i++) {
    const currentNum = parseInt(temp[i].number, 10);
    const prevNum = parseInt(temp[i - 1].number, 10);
    const slope = Math.abs(currentNum - prevNum); // 计算两期数字的差值（斜率）

    slopeMap[temp[i].number] = slope; // 记录该号码的斜率
  }

  // 按斜率从高到低排序，选出差值最大的号码
  const scored = Object.entries(slopeMap)
    .map(([num, slope]) => ({ number: num, slope }))
    .sort((a, b) => b.slope - a.slope);  // 按照斜率排序

  // 选择斜率最大的前32个号码
  const selected = scored.slice(0, 32).map(item => item.number);

  // 如果不足32个号码，则从所有号码中选择剩余号码
  if (selected.length < 32) {
    const remain = allNumbers.filter((n) => !selected.includes(n));
    const needed = 32 - selected.length;
    selected.push(...remain.slice(0, needed));  // 从未选中的号码中按顺序补充
  }

  return selected;
}

// ✅ 预测结果
let correct = 0;
let maxWrongStreak = 0;
let currentWrongStreak = 0;

// ✅ 主循环
allValues.forEach((item, index) => { 
  const temp = useWindow ? allValues.slice(index - windowSize, index) : allValues.slice(0, index);

  if (temp.length === 0) return;

  const selectedNumbers = select32BySlopeAnalysis(temp);

  if (selectedNumbers.length !== 32) {
    throw new Error("选出的32个号码数量不正确");
  }

  try {
    const isHit = checkAccuracy(selectedNumbers, item.number);
    if (isHit) {
      correct += 1;
      currentWrongStreak = 0;
    } else {
      currentWrongStreak += 1;
      maxWrongStreak = Math.max(maxWrongStreak, currentWrongStreak);
    }
  } catch (err) {
    console.error(`❌ checkAccuracy error at index ${index}: ${err.message}`);
  }
});

// ✅ 输出统计结果
const total = allValues.length;
const accuracy = total > 0 ? ((correct / total) * 100).toFixed(2) : 0;

console.log(`预测总数: ${total}`);
console.log(`命中次数: ${correct}`);
console.log(`准确率: ${accuracy}%`);
console.log(`最大连续错误次数: ${maxWrongStreak}`);
